﻿#Region "Imports"
Imports System.IO
Imports Microsoft.LightSwitch.Presentation
Imports Microsoft.LightSwitch.Presentation.Extensions
Imports Microsoft.LightSwitch.Client
Imports Microsoft.LightSwitch.Details
Imports Microsoft.LightSwitch
Imports Microsoft.LightSwitch.Model
Imports System.Runtime.CompilerServices
Imports Microsoft.LightSwitch.Threading
Imports System.Diagnostics
Imports Microsoft.LightSwitch.Framework
Imports System.Reflection
Imports System.Security
Imports System.Runtime.InteropServices
Imports System.Linq.Expressions
Imports Microsoft.LightSwitch.Sdk.Proxy
Imports Microsoft.VisualStudio.ExtensibilityHosting
Imports Microsoft.LightSwitch.Runtime.Shell.Framework
Imports System.Runtime.InteropServices.Automation
Imports System.Collections.ObjectModel
Imports System.Collections.Generic
Imports System.Collections
#End Region

Public Module Outlook
    ' Outlook Appointment Constants
    Const olAppointmentItem As Integer = 1
    Const olMeeting As Integer = 1
    ' Outlook Mail Item Constants
    Const olMailItem As Integer = 0
    Const olFormatPlain As Integer = 1
    Const olFormatHTML As Integer = 2
    ' Outlook Recipient Type Constants
    Const olTo As Integer = 1
    Const olCC As Integer = 2
    Const olBCC As Integer = 3

    Dim outlook As Object = Nothing
    Dim oNS As Object = Nothing

    'Public Sub CreateAppointment(ByVal Address As String,
    Public Function CreateAppointment(ByVal Address As String,
                                      ByVal Subject As String,
                                      ByVal Body As String,
                                      ByVal Location As String,
                                      ByVal StartDateTime As Date,
                                      ByVal EndDateTime As Date) As Object

        Dim result = False

        Try
            If GetOutlook() Then

                'Create the Appointment
                Dim appt = outlook.CreateItem(olAppointmentItem)
                With appt
                    .Body = Body
                    .Subject = Subject
                    .Start = StartDateTime
                    .End = EndDateTime
                    .Location = Location
                    .MeetingStatus = olMeeting
                    .Recipients.Add(Address)
                    .Display()
                    result = True
                End With

                ' Returning the object 
                Return appt
            End If

        Catch ex As Exception
            Throw New InvalidOperationException("Failed to create Appointment.", ex)
        End Try

        Return vbNull
    End Function

    Public Function CreateEmail(ByVal Address() As String,
                                ByVal CCAddress() As String,
                                ByVal Subject As String,
                                ByVal Body As String) As Object

        Try
            If GetOutlook() Then
                Dim mail = outlook.CreateItem(olMailItem)
                With mail
                    If Body.ToLower.Contains("<html>") Then
                        .BodyFormat = olFormatHTML
                        .HTMLBody = Body
                    Else
                        .BodyFormat = olFormatPlain
                        .Body = Body
                    End If

                    ' Add "To" recipients
                    For i As Integer = 0 To Address.Length - 1
                        .Recipients.Add(Address(i))
                    Next

                    ' Add CC Recipients
                    For i As Integer = 0 To CCAddress.Length - 1
                        Dim recipient As Object = .Recipients.Add(CCAddress(i))
                        recipient.Type = olCC
                    Next

                    .Subject = Subject
                    .Display()
                End With
                ' Returning the object 
                Return mail

            End If

        Catch ex As Exception
            Throw New InvalidOperationException("Failed to create email.", ex)
        End Try

        Return vbNull
    End Function

    ' CreateEmail Wrapper Method
    Public Function CreateEmail(ByVal Address As String,
                                ByVal Subject As String,
                                ByVal Body As String) As Object
        Dim Addresses() As String = New String() {Address}
        Dim CCAddresses() As String = New String() {}
        Dim result As Object = CreateEmail(Addresses, CCAddresses, Subject, Body)
        Return result
    End Function

    ' CreateEmail Wrapper Method
    Public Function CreateEmail(ByVal Address As String,
                                ByVal CCAddresses() As String,
                                ByVal Subject As String,
                                ByVal Body As String) As Object

        Dim addresses() As String = New String() {Address}
        Dim result As Object = CreateEmail(addresses, CCAddresses, Subject, Body)
        Return result
    End Function

    ' CreateEmail Wrapper Method
    Public Function CreateEmail(ByVal Addresses() As String,
                                ByVal CCAddress As String,
                                ByVal Subject As String,
                                ByVal Body As String) As Object

        Dim CCAddresses() As String = New String() {CCAddress}
        Dim result As Object = CreateEmail(Addresses, CCAddresses, Subject, Body)
        Return result
    End Function

    ' CreateEmail Wrapper Method
    Public Function CreateEmail(ByVal Address As String,
                                ByVal CCAddress As String,
                                ByVal Subject As String,
                                ByVal Body As String) As Object

        Dim Addresses() As String = New String() {Address}
        Dim CCAddresses() As String = New String() {CCAddress}
        Dim result As Object = CreateEmail(Addresses, CCAddresses, Subject, Body)
        Return result
    End Function

    Public Function CreateEmail(ByVal Address As String,
                                ByVal Subject As String,
                                ByVal Items As IVisualCollection) As Object

        Try
            Dim sBody As String
            sBody = HtmlExport(Items)

            If GetOutlook() Then

                Dim mail = outlook.CreateItem(olMailItem)
                With mail
                    ' checking if it contains an html tags
                    If sBody.ToLower.Contains("<html>") Then
                        .BodyFormat = olFormatHTML
                        .HTMLBody = sBody
                    Else
                        .BodyFormat = olFormatPlain
                        .Body = sBody
                    End If

                    .Recipients.Add(Address)
                    .Subject = Subject
                    .Display()
                End With

                ' Returning the object 
                Return mail
            End If

        Catch ex As Exception
            Throw New InvalidOperationException("Failed to create email.", ex)
        End Try

        Return vbNull
    End Function

    ' Create HTML table based on IVisualCollection
    Public Function HtmlExport(Collection As IVisualCollection, ColumnNames As List(Of String)) As String
        Dim entityObj As IEntityObject
        Dim sBody As String = ""

        If Collection.Count > 0 Then

            ' opening an html tag and creating a table 
            'sBody = "<html>"
            'sBody = sBody + "</br></br>"
            'sBody = sBody + "<body style=""font-family: Arial, Helvetica, sans-serif;"" >"
            sBody = "<table border=""1"">"

            Dim sColumnName As String

            ' add columns names to the list
            ' row begins
            sBody = sBody + "<tr>"
            For Each sColumnName In ColumnNames
                sBody = sBody + "<td>"
                sBody = sBody + " " + sColumnName
                sBody = sBody + "</td>"
            Next
            ' row ends
            sBody = sBody + "</tr>"

            ' iterate the collection and extract values by column name
            For Each entityObj In Collection
                sBody = sBody + "<tr>"
                For i As Integer = 0 To ColumnNames.Count - 1
                    sBody = sBody + "<td>"
                    sBody = sBody + LightSwitchHelper.GetValue(entityObj, ColumnNames(i))
                    sBody = sBody + "</td>"
                Next
                sBody = sBody + "</tr>"
            Next

            ' closing the tags
            sBody = sBody + "</table>"
            'sBody = sBody + "</body>"
            'sBody = sBody + "</html>"

        End If
        HtmlExport = sBody
    End Function


    ' Create HTML table based on IVisualCollection
    Public Function HtmlExport(Collection As IVisualCollection) As String
        Dim entityObj As IEntityObject
        Dim columnNames As List(Of String) = New List(Of String)

        Dim sBody As String = ""

        If Collection.Count > 0 Then

            ' opening an html tag and creating a table 
            'Body = "<html>"
            'sBody = sBody + "</br></br>"
            'sBody = sBody + "<body style=""font-family: Arial, Helvetica, sans-serif;"" >"
            sBody = "<table border=""1"">"

            ' get column properties
            Dim columnProperties As IEnumerable(Of IEntityProperty) = Collection(0).Details.Properties.All()
            Dim entityProperty As IEntityProperty

            ' add columns names to the list
            ' row begins
            sBody = sBody + "<tr>"
            For Each entityProperty In columnProperties
                columnNames.Add(entityProperty.Name)
                sBody = sBody + "<td>"
                sBody = sBody + " " + entityProperty.DisplayName
                sBody = sBody + "</td>"
            Next
            ' row ends
            sBody = sBody + "</tr>"

            ' iterate the collection and extract values by column name
            For Each entityObj In Collection
                sBody = sBody + "<tr>"
                For i As Integer = 0 To columnNames.Count - 1
                    sBody = sBody + "<td>"
                    sBody = sBody + LightSwitchHelper.GetValue(entityObj, columnNames(i))
                    sBody = sBody + "</td>"
                Next
                sBody = sBody + "</tr>"
            Next

            ' closing the tags
            sBody = sBody + "</table>"
            'sBody = sBody + "</body>"
            'sBody = sBody + "</html>"

        End If
        HtmlExport = sBody
    End Function

    ' Create HTML table based on IEntityCollection
    Public Function HtmlExportEntityCollection(Collection As IEntityCollection, ColumnNames As List(Of String)) As String
        Dim entityObj As IEntityObject
        Dim bFirstItem As Boolean = True
        Dim sBody As String = ""

        ' iterate the collection and extract values by column name
        For Each entityObj In Collection
            If bFirstItem Then
                ' opening an html tag and creating a table 
                'sBody = "<html>"
                'sBody = sBody + "</br></br>"
                'sBody = sBody + "<body style=""font-family: Arial, Helvetica, sans-serif;"" >"
                sBody = "<table border=""1"">"

                ' add columns names to the list
                ' row begins
                Dim sColumnName As String
                sBody = sBody + "<tr>"
                For Each sColumnName In ColumnNames
                    sBody = sBody + "<td>"
                    sBody = sBody + " " + sColumnName
                    sBody = sBody + "</td>"
                Next
                ' row ends
                sBody = sBody + "</tr>"
                bFirstItem = False
            End If


            sBody = sBody + "<tr>"
            For i As Integer = 0 To ColumnNames.Count - 1
                sBody = sBody + "<td>"
                sBody = sBody + LightSwitchHelper.GetValue(entityObj, ColumnNames(i))
                sBody = sBody + "</td>"
            Next
            sBody = sBody + "</tr>"
        Next

        ' Add closing tags if there was at least one item
        ' bFirstItem = True by default
        ' It is set to False when the first item is encountered
        If Not bFirstItem Then
            ' closing the tags
            sBody = sBody + "</table>"
            'sBody = sBody + "</body>"
            'sBody = sBody + "</html>"
        End If

        HtmlExportEntityCollection = sBody
    End Function

    ' Create HTML table based on IEnumerable
    Public Function HtmlExport(Collection As IEnumerable, FieldNames As List(Of String)) As String
        Dim entityObj As Object
        Dim bFirstItem As Boolean = True
        Dim sBody As String = ""

        ' iterate the collection and extract values by column name
        For Each entityObj In Collection
            If bFirstItem Then
                ' opening an html tag and creating a table 
                'sBody = "<html>"
                'sBody = sBody + "</br></br>"
                'sBody = sBody + "<body style=""font-family: Arial, Helvetica, sans-serif;"" >"
                sBody = "<table border=""1"">"

                ' add columns names to the list
                ' row begins
                Dim sColumnName As String
                sBody = sBody + "<tr>"
                For Each sColumnName In FieldNames
                    sBody = sBody + "<td>"
                    sBody = sBody + " " + sColumnName
                    sBody = sBody + "</td>"
                Next
                ' row ends
                sBody = sBody + "</tr>"
                bFirstItem = False
            End If


            sBody = sBody + "<tr>"
            For i As Integer = 0 To FieldNames.Count - 1
                sBody = sBody + "<td>"
                sBody = sBody + LightSwitchHelper.GetObjectValue(entityObj, FieldNames(i)).ToString()
                sBody = sBody + "</td>"
            Next
            sBody = sBody + "</tr>"
        Next

        ' Add closing tags if there was at least one item
        ' bFirstItem = True by default
        ' It is set to False when the first item is encountered
        If Not bFirstItem Then
            ' closing the tags
            sBody = sBody + "</table>"
            'sBody = sBody + "</body>"
            'sBody = sBody + "</html>"
        End If

        HtmlExport = sBody
    End Function

    ' Create HTML table based on IEntityCollection
    Public Function HtmlExportEntityCollection(Collection As IEntityCollection) As String
        Dim entityObj As IEntityObject
        Dim columnNames As List(Of String) = New List(Of String)
        Dim bFirstItem As Boolean = True
        Dim sBody As String = ""

        ' get column properties
        Dim columnProperties As IEnumerable(Of IEntityProperty) = Collection(0).Details.Properties.All()
        Dim entityProperty As IEntityProperty

        ' iterate the collection and extract values by column name
        For Each entityObj In Collection
            If bFirstItem Then
                ' opening an html tag and creating a table 
                'sBody = "<html>"
                'sBody = sBody + "</br></br>"
                'sBody = sBody + "<body style=""font-family: Arial, Helvetica, sans-serif;"" >"
                sBody = "<table border=""1"">"

                ' add columns names to the list
                ' row begins
                sBody = sBody + "<tr>"
                For Each entityProperty In columnProperties
                    columnNames.Add(entityProperty.Name)
                    sBody = sBody + "<td>"
                    sBody = sBody + " " + entityProperty.DisplayName
                    sBody = sBody + "</td>"
                Next
                ' row ends
                sBody = sBody + "</tr>"
                bFirstItem = False
            End If


            sBody = sBody + "<tr>"
            For i As Integer = 0 To columnNames.Count - 1
                sBody = sBody + "<td>"
                sBody = sBody + LightSwitchHelper.GetValue(entityObj, columnNames(i))
                sBody = sBody + "</td>"
            Next
            sBody = sBody + "</tr>"
        Next

        ' Add closing tags if there was at least one item
        ' bFirstItem = True by default
        ' It is set to False when the first item is encountered
        If Not bFirstItem Then
            ' closing the tags
            sBody = sBody + "</table>"
            'sBody = sBody + "</body>"
            'sBody = sBody + "</html>"
        End If

        HtmlExportEntityCollection = sBody
    End Function

    Private Function GetOutlook() As Boolean
        Try
            ' If GetObject throws an exception, then Outlook is 
            ' either not running or is not available.
            outlook = AutomationFactory.GetObject("Outlook.Application")
            Return True
        Catch
            Try
                ' Start Outlook and display the Inbox, but minimize 
                ' it to avoid hiding the running application.

                outlook = AutomationFactory.CreateObject("Outlook.Application")
                outlook.Session.GetDefaultFolder(6).Display() ' 6 = Inbox
                outlook.ActiveWindow.WindowState = 1  ' minimized
                Return True
            Catch
                ' Outlook is unavailable.
                Return False
            End Try
        End Try
    End Function
End Module


